package com.etoak.crawl;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.stream.Stream;

/**
 * @author sam
 */
public class Links {

    /**
     * 已访问的 url 集合  已经访问过的 主要考虑 不能再重复了 使用set来保证不重复;
     */
    private static final Set<String> VISITED_URL_SET = new HashSet<>();

    /**
     * 待访问的 url 集合  待访问的主要考虑 1:规定访问顺序;2:保证不提供重复的带访问地址;
     */
    private static final LinkedList<String> UN_VISITED_URL_QUEUE = new LinkedList<>();

    /**
     * 获得已经访问的 URL 数目
     *
     * @return int
     */
    public static int getVisitedUrlNum() {
        return VISITED_URL_SET.size();
    }

    /**
     * 添加到访问过的 URL
     *
     * @param url String
     */
    public static void addVisitedUrlSet(String url) {
        VISITED_URL_SET.add(url);
    }

    /**
     * 移除访问过的 URL
     *
     * @param url url
     */
    public static void removeVisitedUrlSet(String url) {
        VISITED_URL_SET.remove(url);
    }


    /**
     * 获得 待访问的 url 集合
     *
     * @return LinkedList<String>
     */
    public static LinkedList<String> getUnVisitedUrlQueue() {
        return UN_VISITED_URL_QUEUE;
    }

    /**
     * 添加到待访问的集合中  保证每个 URL 只被访问一次
     *
     * @param urls urls
     */
    public static void addUnvisitedUrlQueue(String... urls) {
        Stream.of(urls)
                .filter(Links::isValidUrl)
                .forEach(
                        url -> {
                            UN_VISITED_URL_QUEUE.add(url);
                            System.out.println("Links: 新增爬取路径: " + url);
                        }
                );
    }

    /**
     * 是否是 有效的待访问url
     *
     * @param url url
     * @return boolean
     */
    public static boolean isValidUrl(String url) {
        // url不能是空字符串, 还要排除已访问过的, 也不能重复添加到未访问队列中
        return url != null && !"".equals(url.trim()) && !VISITED_URL_SET.contains(url) && !UN_VISITED_URL_QUEUE.contains(url);
    }

    /**
     * 取出 待访问的url
     *
     * @return String
     */
    public static String fetchHeadOfUnVisitedUrlQueue() {
        String url = UN_VISITED_URL_QUEUE.removeFirst();
        System.out.println("Links: 取出待访问的url : " + url);
        return url;
    }

    /**
     * 判断未访问的 URL 队列中是否为空
     *
     * @return boolean
     */
    public static boolean unVisitedUrlQueueIsEmpty() {
        return UN_VISITED_URL_QUEUE.isEmpty();
    }


    /**
     * 是否有 有效的链接
     *
     * @return boolean
     */
    public static boolean hasUnVisitedUrlList() {
        // 待抓取的链接不空且链接总数不超过 100
        return !UN_VISITED_URL_QUEUE.isEmpty() && Links.getVisitedUrlNum() <= 100;
    }
}
